<!--
 * @Date: 2023-03-22 16:41:45
 * @LastEditTime: 2023-05-05 22:02:21
 * @FilePath: /nlk/src/views/coinExchange/coinExchange.vue
 * 介绍:闪兑
-->
<script lang="ts" setup>
import { parseNumber, _require } from "@@/utils/tools/tools";
import { PickerColumn, PickerConfirmEventParams, showDialog } from "vant";
import useBalanceStore, { StoreCoinItem } from "@@/store/useBalanceStore";
import { useRpopupRef } from "@@/components/rework/Rpopup";
import {
  apiExchangeList,
  apiExchangeToList,
  ExchangeToList,
  ExchangeList,
} from "@@/api/page/coinExchange";
import { divide, multiply } from "mathjs";
import { apiExchange } from "@@/api/module/balance";
import toast from "@@/hooks/toast";
import { checkAuth } from "@@/hooks/sysHooks";
import exchangeLogs from "./components/exchangeLogs.vue";
import CpageView from "@@/components/common/CpageView/CpageView.vue";
import { formatNumber } from "@@/utils/tools/format";

const { t } = useI18n();
const balanceStore = useBalanceStore();
const { coinEnum } = storeToRefs(balanceStore);

/**可以闪兑的币种列表 */
const exchangeList = reactive<ExchangeList.ResItem[]>([]);
const exchangeListId = computed(() => exchangeList.map((v) => v.id));
getExchangeList();
getExchangeToList();
/**获取可以闪兑的币种列表 */
async function getExchangeList() {
  const res = await apiExchangeList();
  if (!res) return;
  exchangeList.push(...res);
  formData.formCoin = res[0].code;
}

const exchangeToList = reactive<ExchangeToList.ResItem[]>([]);
const exchangeToListId = computed(() => exchangeToList.map((v) => v.id));
/**获取可以闪兑接收的币种列表 */
async function getExchangeToList() {
  const res = await apiExchangeToList();
  if (!res) return;
  exchangeToList.push(...res);
  formData.toCoin = res[res.length - 1].code;
}
/**接收币种可用列表 */
const coinToList = computed(() =>
  Object.values(coinEnum.value).filter(
    (v) =>
      exchangeToListId.value.includes(v?.id!) &&
      exchangeToList.filter((val) => val.code === v?.code)[0].is_to_exchange
  )
);
/**发送币种可用列表 */
const coinFromList = computed(() =>
  Object.values(coinEnum.value).filter(
    (v) =>
      exchangeListId.value.includes(v?.id!) &&
      exchangeList.filter((val) => val.code === v?.code)[0].is_exchange
  )
);
/**接收币种信息 */
const currentToCoinInfo = computed<ExchangeList.ResItem | undefined>(
  () => exchangeToList.filter((v) => v.code == formData.toCoin)[0]
);

/**发送币种信息 */
const currentFormCoinInfo = computed<ExchangeList.ResItem | undefined>(
  () => exchangeList.filter((v) => v.code == formData.formCoin)[0]
);

/**发送币种 */
const currentFormCoin = computed(() => coinEnum.value[formData.formCoin]);

/**接收币种 */
const currentToCoin = computed(() => coinEnum.value[formData.toCoin]);

/**picker选择器弹窗 */
const RpopupToRef = useRpopupRef();
const RpopupFormRef = useRpopupRef();
/**切换接受coin */
function onPickerConfirmTo(e: PickerConfirmEventParams) {
  const electCoin = e.selectedOptions[0];
  formData.toCoin = electCoin?.value as string;
  RpopupToRef.value?.close();
}
/**切换发送coin */
function onPickerConfirmForm(e: PickerConfirmEventParams) {
  const electCoin = e.selectedOptions[0];
  formData.formCoin = electCoin?.value as string;
  RpopupFormRef.value?.close();
}
/**picker选择器数据 */
const pickerToData = computed<PickerColumn>(() => {
  return coinToList.value.map((v) => ({
    ...v,
    text: v?.code,
    value: v?.code,
  }));
});
/**picker选择器数据 */
const pickerFromData = computed<PickerColumn>(() => {
  return coinFromList.value.map((v) => ({
    ...v,
    text: v?.code,
    value: v?.code,
  }));
});

const formData = reactive({
  amount: "",
  toCoin: "NLK",
  formCoin: "NLK",
});
watch(
  () => formData.formCoin,
  () => {
    balanceStore.findGameBalance(currentFormCoin.value!);
  },
  {
    deep: true,
    immediate: true,
  }
);
/**接收数量 */
const toAmout = computed({
  get() {
    if (formData.amount === "") return "";
    const formAmount = Number(formData.amount);
    const toPrice = Number(currentToCoinInfo.value?.price!);
    const formPrice = Number(currentFormCoinInfo.value?.price!);
    const formValue = multiply(formAmount, formPrice);
    const toAmount = divide(formValue, toPrice);
    const servicePrice = divide(
      Number(currentFormCoinInfo.value?.exchange_poundage),
      100
    );

    const res = toAmount - multiply(toAmount, servicePrice);
    return Number(parseNumber(res, 8)).toString();
  },
  set(val: StrNumber) {
    const toAmount = Number(val);
    const toPrice = Number(currentToCoinInfo.value?.price!);
    const formPrice = Number(currentFormCoinInfo.value?.price!);
    const toValue = multiply(toAmount, toPrice);
    const formAmount = divide(toValue, formPrice);
    const servicePrice = divide(
      Number(currentToCoinInfo.value?.exchange_poundage),
      100
    );
    const res = divide(formAmount, 1 - servicePrice);
    if (isNaN(res)) return;
    formData.amount = Number(parseNumber(res, 8)).toString();
  },
});

async function onSubmitBtn() {
  const amount = Number(formData.amount);
  const toCoin = currentToCoin.value!;
  const formCoin = currentFormCoin.value!;
  if (!(amount > 0))
    return toast.text(`${t("fa-song-shu-liang-bu-neng-xiao-yu")} : 0`);
  toast.loading();
  const gameBalance = await balanceStore.findGameBalance(
    currentFormCoin.value!
  );
  toast.close();
  if (!(amount <= gameBalance!)) return toast.text(t("yu-e-bu-zu"));
  try {
    await checkAuth(formCoin);
    await checkAuth(toCoin);
    exchange(amount, toCoin, formCoin);
  } catch (error) {
    console.error(error);
  }
}
/**发起闪兑 */
function exchange(amount: number, toCoin: CoinInfo, formCoin: CoinInfo) {
  if (!window.isBnb) return toast.text(t("zan-wei-zhi-chi-ci-lian"));
  showDialog({
    title: t("qing-que-ren"),
    message: `${t("dui-huan")}:${amount}${formCoin.code}为${toCoin.code}`,
  }).then(() => {
    apiExchange({ number: amount, to_id: toCoin.id, from_id: formCoin.id });
  });
}
const exchangeLogsRef = ref<InstanceType<typeof exchangeLogs>>();
const CpageViewRef = ref<InstanceType<typeof CpageView>>();

async function onRefresh() {
  CpageViewRef.value?.pullRefreshStart();
  const res = await exchangeLogsRef.value!.apiReset();
  if (res.type === "err") return CpageViewRef.value?.pullRefreshFail();
  CpageViewRef.value?.pullRefreshSuccess();
}
</script>

<template>
  <CpageView
    @refresh="onRefresh"
    ref="CpageViewRef"
    pull-refresh
    class="coinExchange"
  >
    <div class="auto-MT-md">
      <div class="flex-J-SB T-S-sm">
        <div>{{ $t("fa-song") }}</div>
        <div>
          {{ $t("yu-e")
          }}<span>: {{ formatNumber(currentFormCoin?.gameBalance, 4) }}</span>
        </div>
      </div>
      <Ccard bg="var(--C-B2)" class="border-dashed T-S-sm">
        <!-- 发送 -->
        <VanField
          type="number"
          v-model="formData.amount"
          :placeholder="$t('zhuan-chu-shu-liang')"
        >
          <template #label>
            <div class="flex-A-C">
              <Rimage
                height="80rem"
                width="80rem"
                :src="currentFormCoin?.logo!"
              />
              <span class="ML-xs">{{ currentFormCoin?.code }}</span>
              <Ricon
                class="ML-xs"
                @click="RpopupFormRef?.open"
                r-name="icon-xiajiantou"
              />
            </div>
          </template>
          <template #button>
            <div
              @click="
                formData.amount = currentFormCoin?.gameBalance?.toString() || ''
              "
              class="active"
            >
              max
            </div>
          </template>
        </VanField>
      </Ccard>
      <Cgrid col="3" repeat="1fr" class="T-S-sm">
        <CgridItem justify="start">{{ $t("jie-shou-yu-gu") }}</CgridItem>
        <Ricon color="var(--C-success)" r-name="icon-jiantoushangxia" />
      </Cgrid>
      <Ccard bg="var(--C-B2)" class="border-dashed T-S-sm">
        <!-- 接收 -->
        <VanField
          type="number"
          v-model="toAmout"
          :placeholder="$t('jie-shou-shu-liang')"
        >
          <template #label>
            <div class="flex-A-C">
              <Rimage height="80rem" width="80rem" :src="currentToCoin?.logo" />
              <div class="ML-xs">
                {{ currentToCoin?.code }}
                <Ricon @click="RpopupToRef?.open" r-name="icon-xiajiantou" />
              </div>
            </div>
          </template>
          <template #button>
            <div
              @click="
                formData.amount = currentFormCoin?.gameBalance?.toString() || ''
              "
              class="active"
            >
              max
            </div>
          </template>
        </VanField>
      </Ccard>
      <VanButton
        @click="onSubmitBtn"
        class="MT-lg"
        color="var(--C-success)"
        :size="'large'"
        block
      >
        {{ $t("li-ji-dui-huan") }}
      </VanButton>
      <div class="border-dashed infoCard MT-lg">
        <div>{{ $t("dui-huan-jia-ge") }}</div>
        <div>{{ currentToCoinInfo?.price }}</div>
        <div>{{ $t("zui-shao-jie-shou-shu-liang") }}</div>
        <div>{{ 1 / 0 }}</div>
        <div>{{ $t("jia-ge-hua-dian") }}</div>
        <div>--%</div>
      </div>
      <exchangeLogs ref="exchangeLogsRef" />
      <Rpopup ref="RpopupToRef" :position="'bottom'">
        <van-picker
          @confirm="onPickerConfirmTo"
          @cancel="RpopupToRef?.close"
          :title="$t('qing-xuan-ze')"
          :columns="pickerToData"
        >
          <template #option="{ code, logo }: StoreCoinItem">
            <div class="flex-A-C flex-J-SB" style="width: 5em">
              <Rimage width="1.2em" height="1.2em" :src="logo" />
              <div class="T-A-C" style="width: 3em">{{ code }}</div>
            </div>
          </template>
        </van-picker>
      </Rpopup>
      <Rpopup ref="RpopupFormRef" :position="'bottom'">
        <van-picker
          @confirm="onPickerConfirmForm"
          @cancel="RpopupFormRef?.close"
          :title="$t('qing-xuan-ze')"
          :columns="pickerFromData"
        >
          <template #option="{ code, logo }: StoreCoinItem">
            <div class="flex-A-C flex-J-SB" style="width: 5em">
              <Rimage width="1.2em" height="1.2em" :src="logo" />
              <div class="T-A-C" style="width: 3em">{{ code }}</div>
            </div>
          </template>
        </van-picker>
      </Rpopup>
    </div>
  </CpageView>
</template>

<style lang="less" scoped>
.border-dashed {
  border: dashed 1rem var(--C-T1);
}

.infoCard {
  padding: var(--gap-md);
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  align-items: center;
  gap: var(--gap-sm);
  font-size: var(--T-S-sm);
  & > * {
    &:nth-child(2n + 1) {
      color: var(--C-T4);
    }
    &:nth-child(2n + 2) {
      justify-self: end;
    }
  }
}
</style>
